package com.winit.schedule.task.tracker.runner;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import com.winit.schedule.core.model.AssignedTask;
import com.winit.schedule.core.protocol.command.CompleteTaskRequest;
import com.winit.schedule.core.repository.constants.TaskStatus;
import com.winit.schedule.task.tracker.TaskTracker;
import com.winit.schedule.task.tracker.conf.TaskConfiguration;
import com.winit.schedule.task.tracker.utils.DataConverter;
import com.winit.schedule.task.tracker.utils.RemoteUtil;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 默认的任务运行管理器， 一个任务项对应一个运行管理器 一个JVM可以包含一个任务的； 不同任务项在一个JVM可以包含不同任务的任务项的运行管理器
 * 
 * @author jianke.zhang 2015-4-22 上午9:53:16
 * @since 1.0
 */
public class DefaultTaskManager extends AbstractTaskManager {

    private static transient Logger log = LoggerFactory.getLogger(AbstractTaskManager.class);

    public DefaultTaskManager(TaskTracker taskTracker, AssignedTask task) throws Exception{
        super(taskTracker, task);
    }

    @Override
    protected void completeTask(TaskStatus taskStatus, String exception) {

        // this.getTaskTracker().getManagerMap().get(this.task.getTaskId()).remove(this);

        // 清除任务执行器
        this.getTaskTracker().removeTaskManager(this.getTask().getTaskId(), this);

        // 向JobTracker发送任务完成指令
        log.info("Call task complete request, task status is : " + taskStatus + ", Task Items : "
                  + task.getTaskItems());

        CompleteTaskRequest request = new CompleteTaskRequest();
        request.setTask(this.getTask());
        request.setTaskTrackerUuid(this.getTaskTracker().getUuid());
        request.setTaskRunner(DataConverter.convert2TaskTunner(this));
        request.setTaskStatus(taskStatus);
        request.setException(exception);
        if(!StringUtils.isEmpty(request.getTask().getTaskGroup()) && "MatrixSend_ON".equals(request.getTask().getTaskGroup())){
            httpRequest("http://127.0.0.1:8097/api/v1/usTask/uscheduleRtn?id="+request.getTask().getTaskName()+"&status="+taskStatus.name(),"GET",null);
        }

        sendTaskCompleteCommand(request);
    }

    @Override
    protected void fireTaskExecuteFailure(String exception) {
        CompleteTaskRequest request = new CompleteTaskRequest();
        request.setTask(this.getTask());
        request.setTaskTrackerUuid(this.getTaskTracker().getUuid());
        request.setTaskRunner(DataConverter.convert2TaskTunner(this));
        request.setTaskStatus(TaskStatus.EXECUTE_FAILURE);
        request.setException(StringUtils.isEmpty(exception) ? "Task execution returns false" : exception);

        sendTaskCompleteCommand(request);
    }

    private void sendTaskCompleteCommand(CompleteTaskRequest request) {
        if (null != request.getTask().getTaskItems() && request.getTask().getTaskItems().size() == 1) {
            request.setIdentity(request.getTask().getTaskItems().get(0).getTaskItemId());
        }
        boolean success = RemoteUtil.sendTaskCompleteCommand(request, this.getTaskTracker().getRemotingClientService());
        if (!success) {
            log.error("Submit the completed task request failed, request parameter:" + request);

            // 加入重试队列
            int maxRetryTimes = this.getTaskTracker()
                .getConf()
                .getInt(TaskConfiguration.RPC_RETRY_TIMES, TaskConfiguration.DEFAULT_RPC_RETRY_TIMES);
            this.getTaskTracker().getRpcRetryService().addRetryTask(request, maxRetryTimes);
        }
    }

    public static String httpRequest(String requestUrl,String requestMethod,String outputStr){
        StringBuffer buffer=null;
        try{
            URL url=new URL(requestUrl);
            HttpURLConnection conn=(HttpURLConnection)url.openConnection();
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod(requestMethod);
            conn.connect();
            //往服务器端写内容 也就是发起http请求需要带的参数
            if(null!=outputStr){
                OutputStream os=conn.getOutputStream();
                os.write(outputStr.getBytes("utf-8"));
                os.close();
            }

            //读取服务器端返回的内容
            InputStream is=conn.getInputStream();
            InputStreamReader isr=new InputStreamReader(is,"utf-8");
            BufferedReader br=new BufferedReader(isr);
            buffer=new StringBuffer();
            String line=null;
            while((line=br.readLine())!=null){
                buffer.append(line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return buffer.toString();
    }
}
